/*
 * @(#)GraphSelectionModel.java	0.1 03-JUL-04
 * 
 * Copyright (c) 2001-2004 Gaudenz Alder
 *  
 */
package org.jgraph.graph;

import java.beans.PropertyChangeListener;

import org.jgraph.event.GraphSelectionListener;

/**
 * This interface represents the current state of the selection for the graph
 * component.
 * <p>
 * 
 * A GraphSelectionModel can be configured to allow only one cell (<code>SINGLE_GRAPH_SELECTION</code>)
 * or a number of cells (<code>MULTIPLE_GRAPH_SELECTION</code>).
 * 
 * @version 0.1 1/1/02
 * @author Gaudenz Alder
 */

public interface GraphSelectionModel {

	/** Selection can only contain one cell at a time. */
	public static final int SINGLE_GRAPH_SELECTION = 1;

	/** Selection can contain any number of items. */
	public static final int MULTIPLE_GRAPH_SELECTION = 4;

	/**
	 * Sets the selection model, which must be either SINGLE_GRAPH_SELECTION or
	 * MULTIPLE_GRAPH_SELECTION.
	 * <p>
	 * This may change the selection if the current selection is not valid for
	 * the new mode.
	 */
	void setSelectionMode(int mode);

	/**
	 * Sets if the selection model allows the selection of children.
	 */
	void setChildrenSelectable(boolean flag);

	/**
	 * Returns true if the selection model allows the selection of children.
	 */
	boolean isChildrenSelectable();

	/**
	 * Returns the current selection mode, either
	 * <code>SINGLE_GRAPH_SELECTION</code> or
	 * <code>MULTIPLE_GRAPH_SELECTION</code>.
	 */
	int getSelectionMode();

	/**
	 * Sets the selection to cell. If this represents a change, then the
	 * GraphSelectionListeners are notified. If <code>cell</code> is null,
	 * this has the same effect as invoking <code>clearSelection</code>.
	 * 
	 * @param cell
	 *            new cell to select
	 */
	void setSelectionCell(Object cell);

	/**
	 * Sets the selection to cells. If this represents a change, then the
	 * GraphSelectionListeners are notified. If <code>cells</code> is null,
	 * this has the same effect as invoking <code>clearSelection</code>.
	 * 
	 * @param cells
	 *            new selection
	 */
	void setSelectionCells(Object[] cells);

	/**
	 * Adds cell to the current selection. If cell is not currently in the
	 * selection the GraphSelectionListeners are notified. This has no effect if
	 * <code>cell</code> is null.
	 * 
	 * @param cell
	 *            the new cell to add to the current selection
	 */
	void addSelectionCell(Object cell);

	/**
	 * Adds cells to the current selection. If any of the cells are not
	 * currently in the selection the GraphSelectionListeners are notified. This
	 * has no effect if <code>cells</code> is null.
	 * 
	 * @param cells
	 *            the new cells to add to the current selection
	 */
	void addSelectionCells(Object[] cells);

	/**
	 * Removes cell from the selection. If cell is in the selection the
	 * GraphSelectionListeners are notified. This has no effect if
	 * <code>cell</code> is null.
	 * 
	 * @param cell
	 *            the cell to remove from the selection
	 */
	void removeSelectionCell(Object cell);

	/**
	 * Removes cells from the selection. If any of the cells in
	 * <code>cells</code> are in the selection, the GraphSelectionListeners
	 * are notified. This method has no effect if <code>cells</code> is null.
	 * 
	 * @param cells
	 *            the cells to remove from the selection
	 */
	void removeSelectionCells(Object[] cells);

	/**
	 * Returns the cells that are currently selectable.
	 */
	Object[] getSelectables();

	/**
	 * Returns the first cell in the selection. How first is defined is up to
	 * implementors.
	 */
	Object getSelectionCell();

	/**
	 * Returns the cells in the selection. This will return null (or an empty
	 * array) if nothing is currently selected.
	 */
	Object[] getSelectionCells();

	/**
	 * Returns the number of cells that are selected.
	 */
	int getSelectionCount();

	/**
	 * Returns true if the cell, <code>cell</code>, is in the current
	 * selection.
	 */
	boolean isCellSelected(Object cell);

	/**
	 * Returns true if the cell, <code>cell</code>, has selected children.
	 */
	boolean isChildrenSelected(Object cell);

	/**
	 * Returns true if the selection is currently empty.
	 */
	boolean isSelectionEmpty();

	/**
	 * Empties the current selection. If this represents a change in the current
	 * selection, the selection listeners are notified.
	 */
	void clearSelection();

	/**
	 * Adds a PropertyChangeListener to the listener list. The listener is
	 * registered for all properties.
	 * <p>
	 * A PropertyChangeEvent will get fired when the selection mode changes.
	 * 
	 * @param listener
	 *            the PropertyChangeListener to be added
	 */
	void addPropertyChangeListener(PropertyChangeListener listener);

	/**
	 * Removes a PropertyChangeListener from the listener list. This removes a
	 * PropertyChangeListener that was registered for all properties.
	 * 
	 * @param listener
	 *            the PropertyChangeListener to be removed
	 */
	void removePropertyChangeListener(PropertyChangeListener listener);

	/**
	 * Adds x to the list of listeners that are notified each time the set of
	 * selected Objects changes.
	 * 
	 * @param x
	 *            the new listener to be added
	 */
	void addGraphSelectionListener(GraphSelectionListener x);

	/**
	 * Removes x from the list of listeners that are notified each time the set
	 * of selected Objects changes.
	 * 
	 * @param x
	 *            the listener to remove
	 */
	void removeGraphSelectionListener(GraphSelectionListener x);
}
